import { resolvePath } from 'react-router-dom';
import React, { lazy } from 'react';
import _ from 'lodash';

import { RoutesType, RouteItemType } from '@customTypes/customTypes';
import Icons from '@/components/Icons';

const BasicOutlet = lazy((): Promise<any> => import('@layouts/BasicLayout'));

/**
 * 路径替换
 * 先把结尾的 一个或多个 / => '' ;
 * 再把开头的 /* -> /
 */
export const normalizePathname = (pathname: string) =>
  pathname.replace(/\/+$/, '').replace(/^\/*/, '/');

/**
 * 根据routes里的格式, 解析出全局的路由, 构造好路由结构
 */
export function generateRoute(routes: RoutesType[]) {
  const generateConfig = (config: RoutesType[], basePath: string) => {
    return config.map((conf: RoutesType) => {
      // 根据路径生成一个{ pathname, search, hash } 对象
      const pathObj = resolvePath(
        conf.path ? _.replace(conf.path, '/*', '') : '/*',
        normalizePathname(basePath)
      );

      const { name, index, path, component } = conf;
      let Element;
      // 存在地址但不存在组件，说明它是包含子路由的
      if (path && !component) {
        Element = BasicOutlet;
      } else {
        Element = component;
      }

      const routeItem: RouteItemType = {
        name,
        index,
        // 完整路径
        fullPath: pathObj.pathname,
        key: pathObj.pathname,
        element: Element ? <Element /> : null
      };

      if (conf.path) {
        routeItem.path = conf.path;
      }

      // 递归遍历子路由
      if (conf.children) {
        routeItem.children = generateConfig(conf.children, pathObj.pathname);
      }

      return routeItem;
    });
  };

  const newRoutes = generateConfig(routes, '/');

  return newRoutes;
}

/**
 * 根据请求返回, 构造好ProLayout的menu结构
 */
export function generateMenu(menus: any[]) {
  const generateConfig = (config: any[], basePath: string) => {
    return config.map((conf: any) => {
      // 根据路径生成一个{ pathname, search, hash } 对象
      const pathObj = resolvePath(
        conf.path ? _.replace(conf.path, '/*', '') : '/*',
        normalizePathname(basePath)
      );

      const { name, id, icon } = conf;
      const menuItem: Record<string, any> = {
        name,
        // 完整路径
        fullPath: pathObj.pathname,
        key: id,
        component: <></>,
        icon: icon ? React.createElement(Icons, { type: icon }) : null
      };

      // 支持prolayout路由
      if (conf.path) {
        menuItem.path = conf.path;
      }

      // 递归遍历子路由
      if (conf.children) {
        menuItem.children = generateConfig(conf.children, pathObj.pathname);
      }

      return menuItem;
    });
  };

  const newMenus = !_.isArray(menus) || _.isEmpty(menus) ? [] : generateConfig(menus, '/');

  return newMenus;
}
